package org.aplikator.server.descriptor;

import org.aplikator.server.persistence.PersisterFactory;

import java.io.Serializable;

public class Reference<R extends Entity> extends Property<Integer> {

    public R referredEntity;

    @SuppressWarnings("unchecked")
    public Reference(String id, R referredEntity, Entity ownEntity) {
        super(id, Integer.class, 0, false, ownEntity); // TODO change when PK is
                                                       // more general
        if (ownEntity.equals(referredEntity)) {
            try {
                this.referredEntity = (R) referredEntity.clone();
            } catch (CloneNotSupportedException e) {
                throw new IllegalStateException(e);
            }
        } else {
            this.referredEntity = referredEntity;
        }
    }

    public <T extends Serializable> Property<T> relate(Property<T> target) {
        Property<T> related;
        try {
            related = target.clone();
        } catch (CloneNotSupportedException e) {
            throw new IllegalStateException(e);
        }
        PersisterFactory.getPersister().registerPropertyClone(target, related);
        related.setRefferedThrough(this);
        return related;
    }

    @SuppressWarnings("unchecked")
    public <T extends Entity> Reference<T> join(Reference<T> target){
        return (Reference<T>) relate(target);
    }
}
